#pragma once
#include <iostream>
#include <unistd.h>
#include <sys/epoll.h>
#include "Log.hpp"

using namespace std;

class Epoll
{
    static const int gnum = 128;

public:
    Epoll()
    {
    }
    void EpollCreate()
    {
        _epfd = epoll_create(gnum);
        if (_epfd < 0)
        {
            logMessage(ERROR, "epoll create fail!\n");
            exit(5);
        }
    }
    ~Epoll()
    {
        if (_epfd > 0)
            close(_epfd);
    }
    void AddSockToEpoll(int sock, uint32_t events) // 添加套接字事件到epoll中
    {
        struct epoll_event evs;
        evs.data.fd = sock;
        evs.events = events;

        int n = epoll_ctl(_epfd, EPOLL_CTL_ADD, sock, &evs);
        if (n < 0)
        {
            logMessage(ERROR, "add sock to epoll fail!\n");
            exit(6);
        }
    }
    void DelSockFromEpoll(int sock)
    {
        int n = epoll_ctl(_epfd, EPOLL_CTL_DEL, sock, NULL); // 删掉sock的所有关心事件
        if (n < 0)
        {
            logMessage(ERROR, "del sock from epoll fail!\n");
            exit(8);
        }
    }
    void EpollCtl(int sock, uint32_t events)
    {
        struct epoll_event evs;
        evs.data.fd = sock;
        evs.events = events | EPOLLET; // 边缘触发

        int n = epoll_ctl(_epfd, EPOLL_CTL_MOD, sock, &evs);
        if (n < 0)
        {
            logMessage(ERROR, "mod sock in epoll fail!\n");
            exit(9);
        }
    }
    int EpollWait(struct epoll_event revs[], int revs_num, int timeout = -1) // 让epoll获取一次就绪事件，放入就绪数组中
    {
        int n = epoll_wait(_epfd, revs, revs_num, timeout); // 默认阻塞获取
        return n;
    }
    int getEpollfd()
    {
        return _epfd;
    }

private:
    int _epfd;
};